package com.um.jdy.mp.baofu.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.um.jdy.baofu.api.BaoFuAccountService;
import com.um.jdy.baofu.entity.account.*;
import com.um.jdy.baofu.utils.FormatUtil;
import com.um.jdy.common.baofu.entity.po.BaofuUser;
import com.um.jdy.common.baofu.service.BaofuService;
import com.um.jdy.common.base.enums.YesOrNo;
import com.um.jdy.common.finance.entity.po.MerchantBill;
import com.um.jdy.common.finance.entity.po.MerchantCashout;
import com.um.jdy.common.finance.entity.po.PlatformBill;
import com.um.jdy.common.finance.entity.po.PlatformProfitBill;
import com.um.jdy.common.finance.enums.FinancialEnum;
import com.um.jdy.common.finance.service.MerchantBillService;
import com.um.jdy.common.finance.service.MerchantCashoutService;
import com.um.jdy.common.finance.service.PlatformBillService;
import com.um.jdy.common.finance.service.PlatformProfitBillService;
import com.um.jdy.common.member.enums.PayEnum;
import com.um.jdy.common.platform.code.PlatformCode;
import com.um.jdy.common.platform.entity.po.Merchant;
import com.um.jdy.common.platform.entity.po.WithdrawSetting;
import com.um.jdy.common.platform.service.WithdrawSettingService;
import com.um.jdy.mp.baofu.entity.dto.BaofuUserDTO;
import com.um.jdy.mp.baofu.entity.vo.BaofuUserItemVO;
import com.um.jdy.mp.user.service.SessionUserService;
import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.orm.entity.Response;
import com.um.springboot.starter.orm.manager.BaseManager;
import com.um.springboot.starter.orm.params.PageParams;
import com.um.springboot.starter.utils.PayUtil;
import com.um.springboot.starter.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

@Component
@Slf4j
public class BaofuManager extends BaseManager<BaofuService> {
    @Autowired
    private BaoFuAccountService baoFuAccountService;

    @Autowired
    private SessionUserService sessionUserService;
    @Autowired
    private WithdrawSettingService withdrawSettingService;

    @Autowired
    private MerchantCashoutService merchantCashoutService;

    @Autowired
    private MerchantBillService merchantBillService;

    @Autowired
    private PlatformBillService platformBillService;

    @Autowired
    private PlatformProfitBillService platformProfitBillService;

    /**
     * 分页查询宝付用户信息
     * @return
     */
    public Response<Page<BaofuUserItemVO>> page(PageParams pageParams) {
        Page<BaofuUserItemVO> page = new Page<>();
        page.setPageSize(pageParams.getPageSize());
        page.setPageNo(pageParams.getPageNo());
        pageParams.getCondition().put("u.com_id",getComId());
        pageParams.getCondition().put("u.is_delete", "0");
        page = service.getCMSViewModelPageBySqlName(page, "get_baofu_user_page", "get_baofu_user_count",
                BaofuUserItemVO.class, pageParams.getProperties(), pageParams.getValues(),
                pageParams.getRangeEntitys(), pageParams.getOrderNames(), pageParams.getSortOns());
        return Response.success(page);
    }

    public Response<BaofuUser> addEntity(BaofuUserDTO dto) {
        //certificate_no 身份证号码(当为个人时上送身份证号，企业时上送营业执照号) 严重唯一
        //login_no 登录号严重唯一
        //默认身份证 默认企业只能对公
        if(dto.getAccType() == 1){
            if(StrUtil.isBlank(dto.getMobileNo())){
                throw new ServiceException("银行预留手机号不能为空");
            }
        }else {
            if(dto.getSelfEmployed() == null){
                throw new ServiceException("是否为个体户不能为空");
            }
            if(StrUtil.isBlank(dto.getEmail())){
                throw new ServiceException("邮箱不能为空");
            }
            if(StrUtil.isBlank(dto.getCorporateName())){
                throw new ServiceException("法人姓名不能为空");
            }

            if(StrUtil.isBlank(dto.getCorporateCertId())){
                throw new ServiceException("法人身份证号码不能为空");
            }
            if(StrUtil.isBlank(dto.getIndustryId())){
                throw new ServiceException("公司所属行业不能为空");
            }
            if(StrUtil.isBlank(dto.getBankName())){
                throw new ServiceException("银行名称不能为空");
            }
            if(StrUtil.isBlank(dto.getDepositBankProvince())){
                throw new ServiceException("开户行省份不能为空");
            }
            if(StrUtil.isBlank(dto.getDepositBankCity())){
                throw new ServiceException("开户行城市不能为空");
            }
            if(StrUtil.isBlank(dto.getDepositBankName())){
                throw new ServiceException("开户支行名称不能为空");
            }
        }
        if(dto.getCardType() != null && dto.getCardType() == 2) {
            if (StrUtil.isBlank(dto.getCorporateMobile())) {
                throw new ServiceException("法人手机号不能为空");
            }
            if (StrUtil.isBlank(dto.getCardUserName())) {
                throw new ServiceException("持卡人姓名不能为空");
            }
        }
        //service.getEntity(new String[]{"platform_merchant_id", "device_pile_id"}, new Object[]{sessionUserService.getTokenUserId(), devicePileId});
//        if(service.getEntity("certificate_no",dto.getCertificateNo()) != null){
//            throw new ServiceException("此证件照已开户，请勿重复开户！");
//        }
        BaofuUser baofuUser1 = service.getEntity(new String[]{"certificate_no", "state"}, new Object[]{dto.getCertificateNo(), 1});
        if(baofuUser1 != null){
            return Response.success(baofuUser1);
        }
        BCT3100200101Entity bodyInfo= new BCT3100200101Entity();
        AccInfoEntity accinfoEntity = new AccInfoEntity();
        accinfoEntity.setTransSerialNo("TSN"+ FormatUtil.CreateAeskey(20));//每次不重复
        accinfoEntity.setLoginNo("LN"+ FormatUtil.CreateRandNum(15));//登录号商户端用户唯一标识，商户自定义（不重复）
        accinfoEntity.setCustomerName(dto.getCustomerName());//个人：客户名称与持卡人姓名一致 企业：商户名称（营业执照上的名称）
        accinfoEntity.setCertificateNo(dto.getCertificateNo());//个人：身份证号码，企业：营业执照证件号码
        accinfoEntity.setCardNo(dto.getCardNo());//个人：对私卡号，企业：对公卡号，（个体可绑法人对私卡号）
        //默认不传附件
        accinfoEntity.setNeedUploadFile(false);//是否需要上传附件,true/false
        bodyInfo.setAccType(dto.getAccType());
        if(dto.getAccType() == 1){
            //bodyInfo.setAccType(1);//账户类型:1-个人,2-企业/个体
            accinfoEntity.setCertificateType("ID");
            accinfoEntity.setMobileNo(dto.getMobileNo());
        }else {
           // bodyInfo.setAccType(2);//账户类型:1-个人,2-企业/个体
            accinfoEntity.setCertificateType("LICENSE");
            accinfoEntity.setEmail(dto.getEmail());
            accinfoEntity.setSelfEmployed(dto.getSelfEmployed() == 1);
            accinfoEntity.setCorporateName(dto.getCorporateName());
            accinfoEntity.setCorporateCertType("ID");
            accinfoEntity.setCorporateCertId(dto.getCorporateCertId());

            accinfoEntity.setCorporateMobile(dto.getCorporateMobile());
            accinfoEntity.setIndustryId(dto.getIndustryId());
            accinfoEntity.setBankName(dto.getBankName());
            accinfoEntity.setDepositBankProvince(dto.getDepositBankProvince());
            accinfoEntity.setDepositBankCity(dto.getDepositBankCity());
            accinfoEntity.setDepositBankName(dto.getDepositBankName());
            //accinfoEntity.setRegisterCapital(RegisterCapital);
        }
        if(accinfoEntity.isNeedUploadFile()){
            accinfoEntity.setQualificationTransSerialNo("");//[必传]资质文件流水,是否上传请咨询业务对接人
        }

        bodyInfo.setAccInfo(accinfoEntity);//开户具体信息根据类型不同,信息不同,现只支持单笔开户
        JSONObject json =  baoFuAccountService.BCT3_1002_001_01(bodyInfo);
        if(json != null){
            BaofuUser baofuUser = BeanUtil.copyProperties(accinfoEntity, BaofuUser.class);
            baofuUser.setState(json.getInteger("state"));
            baofuUser.setAccType(dto.getAccType() == 1?1:dto.getSelfEmployed()==1?2:3);
            baofuUser.setCreateTime(new Date());
            //baofuUser.setLoginNo(accinfoEntity.getLoginNo());
            //baofuUser.setTransSerialNo(accinfoEntity.getTransSerialNo());
            return Response.success(service.addEntity(baofuUser));
        } else {
            throw new ServiceException("开户失败");
        }

    }

    public void accountReceiveProcess(JSONObject data){
        BaofuUser baofuUser = service.getEntity("login_no",data.getString("loginNo"));
        if(baofuUser != null){
            Integer state = data.getInteger("state");
            baofuUser.setState(state);
            baofuUser.setContractNo(data.getString("contractNo"));
            baofuUser.setUpdateTime(new Date());
            if(state != null && state != 1){
                baofuUser.setErrorMsg(data.getString("errorMsg"));
            }
            service.updateEntity(baofuUser);
        }
    }

    public BaofuUser getById(String id){
        return service.getEntity(id);
    }

    /**
     * 宝付提现
     *
     * @param amount
     */
    public void BaofuCashout(Integer amount) {
        //amount = NumberUtil.round(StringUtil.toDouble(amount) * 100, 0, RoundingMode.UP).intValue();
        cashout(amount, PayEnum.CashOutType.Baofu.name());
    }

    /**
     * 提现
     *
     * @param amount
     */
    @Transactional
    public void cashout(Integer amount, String type) {
        Merchant account = sessionUserService.getTokenUser();
        if(StrUtil.isBlank(account.getBaofuUserId())){
            throw new ServiceException("未开户，不支持提现");
        }
        BaofuUser baofuUser = service.getEntity(account.getBaofuUserId());
        if(baofuUser == null || baofuUser.getState() != 1){
            throw new ServiceException("未开户，不支持提现");
        }
        //校验提现设置
        WithdrawSetting cashoutSetting = this.getCashoutSetting();


        RsultBalanceEntity balanceEntity = baoFuAccountService.BCT3_2001_001_01(baofuUser.getContractNo(),baofuUser.getAccType()==1?1:2);

        //校验提现金额
        Integer canCashout = balanceEntity.getAvailableBal().multiply(BigDecimal.valueOf(100)).intValue();
        if (canCashout < amount) {
            throw new ServiceException(PlatformCode.NoBalance);
        }

        //Integer handFee = (int) (amount * StringUtil.toDouble(cashoutSetting.getHandFee()) / 100);
        //保存提现提现申请
        MerchantCashout merchantCashout = new MerchantCashout();
        merchantCashout.setComId(account.getComId());
        merchantCashout.setAmount(amount);
        merchantCashout.setHandFee(0);
        merchantCashout.setMemberUserId(sessionUserService.getTokenUserId()); //申请用户id
        merchantCashout.setStatus(FinancialEnum.CashoutStatus.Pending.name());
        merchantCashout.setCreateTime(new Date());
        merchantCashout.setType(type);
        merchantCashout.setPlatformMerchantId(sessionUserService.getTokenUserId());

//        if (!bankCardId.isEmpty() && PayEnum.CashOutType.Bank.name().equals(type)) {
//            merchantCashout.setPlatformBankCardId(bankCardId);
//        }
//
        merchantCashoutService.saveEntity(merchantCashout);

        //校验是否需要自动审核通过
        if (ObjectUtil.isNotEmpty(account) && StringUtil.equals(account.getCashoutAuditType(), FinancialEnum.CashoutAuditType.Auto.name())) {
            try {
                String cashoutId = StringUtil.getTrim(merchantCashout.getFinanceMerchantCashoutId());
                this.cashoutPass(account, cashoutId, type,baofuUser);
            } catch (Exception e) {
                log.error("自动审批提现失败，失败原因：", e);
            }
        }
    }

    /**
     * 查询提现设置
     *
     * @return
     */
    public WithdrawSetting getCashoutSetting() {
        return withdrawSettingService.getEntity(new String[]{"com_id", "is_delete"}, new String[]{getComId(), "0"});
    }
    public void cashoutPass(Merchant account,String cashoutId, String type,BaofuUser baofuUser) {
        //修改提现状态
        MerchantCashout cashout = merchantCashoutService.getEntity("finance_merchant_cashout_id", cashoutId);
        if (null == cashout) {
            throw new ServiceException(PlatformCode.NoCashout);
        }

        if (!StringUtil.equals(cashout.getStatus(), FinancialEnum.CashoutStatus.Pending.name())) {
            throw new ServiceException(PlatformCode.CashoutApproved);
        }

        Merchant merchant = sessionUserService.getTokenUser();
        String outTradeNo = PayUtil.getOutTradeNo();
        int amount = StringUtil.toInt(cashout.getAmount());
        //int handFee = StringUtil.toInt(cashout.getHandFee());
       // amount = amount - handFee;//提现金额-手续费

        //更新提现状态
        //cashout.setStatus(FinancialEnum.CashoutStatus.Passed.name());
        //cashout.setHandFee(handFee);
        cashout.setApproveTime(new Date());
        cashout.setApprover("system");//自动审核
        cashout.setOutTradeNo(outTradeNo);

        TransAccountEntity tracce = new TransAccountEntity();
        tracce.setContractNo(baofuUser.getContractNo());
        tracce.setTransSerialNo(outTradeNo);
        tracce.setFeeMemberId(baofuUser.getContractNo());
        tracce.setReqReserved(cashoutId);
        tracce.setDealAmount(BigDecimal.valueOf(amount).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP));
        baoFuAccountService.BCT3_3002_001_01(tracce);
        cashout.setStatus(FinancialEnum.CashoutStatus.PendingLoan.name());
        merchantCashoutService.save(cashout);

    }

    public void cashoutReceive(TiXianResVo tiXianResVo) {
        //处理中不做处理
        if("2".equals(tiXianResVo.getState())){
            return;
        }
        //修改提现状态
        MerchantCashout cashout = merchantCashoutService.getEntity("out_trade_no", tiXianResVo.getTransSerialNo());
        if("1".equals(tiXianResVo.getState())){//成功
            //金额
            int amount = tiXianResVo.getTransMoney().multiply(BigDecimal.valueOf(100)).intValue();
            //手续费
            int handFee = tiXianResVo.getTransFee().multiply(BigDecimal.valueOf(100)).intValue();

            amount = amount - handFee;//提现金额-手续费
            cashout.setStatus(FinancialEnum.CashoutStatus.Passed.name());
            cashout.setHandFee(handFee);
            String status = FinancialEnum.BillStatus.Effective.name();
            MerchantBill merchantBill = new MerchantBill();
            merchantBill.setComId(cashout.getComId());
            merchantBill.setPlatformMerchantId(cashout.getPlatformMerchantId());
            merchantBill.setOutTradeNo(tiXianResVo.getTransSerialNo());
            merchantBill.setAmount(amount);
            merchantBill.setCreateTime(new Date());
            merchantBill.setType(FinancialEnum.IncomeOrExpend.Expend.name());
            merchantBill.setStatus(status);
            merchantBill.setEvent(FinancialEnum.MerchantBillEvent.Cashout.name());
            merchantBill.setNo(StrUtil.builder(DateUtil.date().toString(DatePattern.PURE_DATETIME_MS_PATTERN), RandomUtil.randomNumbers(4)).toString());
            merchantBillService.save(merchantBill);

            MerchantBill merchantBill1 = new MerchantBill();
            merchantBill1.setComId(cashout.getComId());
            merchantBill1.setPlatformMerchantId(cashout.getPlatformMerchantId());
            merchantBill1.setOutTradeNo(tiXianResVo.getTransSerialNo());
            merchantBill1.setAmount(handFee);
            merchantBill1.setCreateTime(new Date());
            merchantBill1.setType(FinancialEnum.IncomeOrExpend.Expend.name());
            merchantBill1.setStatus(status);
            merchantBill1.setEvent(FinancialEnum.MerchantBillEvent.HandFee.name());
            merchantBill1.setNo(StrUtil.builder(DateUtil.date().toString(DatePattern.PURE_DATETIME_MS_PATTERN), RandomUtil.randomNumbers(4)).toString());
            merchantBillService.save(merchantBill1);

            //添加提现流水
            PlatformBill platformBill = new PlatformBill();
            platformBill.setOutTradeNo(tiXianResVo.getTransSerialNo());
            platformBill.setAmount(amount);
            platformBill.setCreateTime(new Date());
            platformBill.setType(FinancialEnum.IncomeOrExpend.Expend.name());
            platformBill.setStatus(status);
            platformBill.setEvent(FinancialEnum.PlatformBillEvent.Cashout.name());
            platformBill.setNo(StrUtil.builder(DateUtil.date().toString(DatePattern.PURE_DATETIME_MS_PATTERN), RandomUtil.randomNumbers(4)).toString());
            platformBillService.save(platformBill);

            //添加手续费流水
            PlatformProfitBill platformProfitBill = new PlatformProfitBill();
            platformProfitBill.setOutTradeNo(tiXianResVo.getTransSerialNo());
            platformProfitBill.setAmount(handFee);
            platformProfitBill.setCreateTime(new Date());
            platformProfitBill.setType(FinancialEnum.IncomeOrExpend.Income.name());
            platformProfitBill.setStatus(status);
            platformProfitBill.setEvent(FinancialEnum.PlatformBillEvent.HandFee.name());
            platformProfitBill.setNo(StrUtil.builder(DateUtil.date().toString(DatePattern.PURE_DATETIME_MS_PATTERN), RandomUtil.randomNumbers(4)).toString());
            platformProfitBillService.save(platformProfitBill);

        }else{//失败
            cashout.setStatus(FinancialEnum.CashoutStatus.LoanFailed.name());
        }

        merchantCashoutService.save(cashout);
    }

}
